﻿/*   
    Copyright (C) 2009 Galaktika Corporation ZAO

    This file is a part of Galaktika.BusinessMonitor
 
    Galaktika.BusinessMonitor is a free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
      
    You should have received a copy of the GNU General Public License
    along with Galaktika.BusinessMonitor.  If not, see <http://www.gnu.org/licenses/>.
  
    If GPL v.3 is not suitable for your products or company,
    Galaktika Corp provides Galaktika.BusinessMonitor under a flexible commercial license
    designed to meet your specific usage and distribution requirements.
    If you have already obtained a commercial license from Galaktika Corp,
    you can use this file under those license terms.
*/

using System;
using System.Collections.Generic;
using System.Windows;

namespace Galaktika.BI.Silverlight.ClientApp
{
    public class LayoutItemBase
    {
        public LayoutItemBase(string name)
        {
            this.Name = name;
            this.Properties = new Dictionary<string, string>();
        }

        private static double Parse(string text, string propertyName)
        {
            double value = 0;
            int startIndex = 0;
            while (startIndex < text.Length)
            {
                int index = text.IndexOf("@", startIndex);
                if (index == -1)
                {
                    return value;
                }
                startIndex = index + 1;
                string[] strArray = text.Substring(startIndex).Split(new char[] { ',', '=' });
                if ((strArray == null) || (strArray.Length < 2))
                {
                    return value;
                }
                int length = Convert.ToInt32(strArray[0]);
                string str2 = strArray[1];
                index = (startIndex + text.Substring(startIndex).IndexOf("=")) + 1;
                if (propertyName == str2)
                {
                    string str3 = text.Substring(index, length);
                    startIndex = index + length;
                    value = Convert.ToDouble(str3);
                }
            }
            return value;
        }

        private static Rect ParseRect(string rect)
        {
            if (string.IsNullOrEmpty(rect))
            {
                throw new ArgumentNullException("rect");
            }

            string[] rectParts = rect.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

            if (rectParts.Length == 0)
            {
                string exception = Localization.Exc_InvalidRectangleFormat;  
                throw new FormatException(string.Format(exception, rect));
            }

            if (rectParts.Length == 4)
            {
                return new Rect(
                    Convert.ToDouble(rectParts[0]),
                    Convert.ToDouble(rectParts[1]),
                    Convert.ToDouble(rectParts[2]),
                    Convert.ToDouble(rectParts[3]));
            }

            double size = Convert.ToDouble(rectParts[0]);
            return new Rect(size, size, size, size);
        }

        private static double ParseX(string p)
        {
            return Parse(p, "X");
        }

        private static double ParseY(string p)
        {
            return Parse(p, "Y");
        }

        private static double ParseHeight(string p)
        {
            return Parse(p, "Height");
        }

        private static double ParseWidth(string value)
        {
            return Parse(value, "Width");
        }

        private Size m_Size = default(Size);
        public Size Size
        {
            get
            {
                if (m_Size == default(Size))
                {
                    if (!this.Properties.ContainsKey("Size"))
                    {
                        return m_Size;
                    }
                    string size = this.Properties["Size"];
                    m_Size = new Size(ParseWidth(size), ParseHeight(size));
                }

                return m_Size;
            }
            set
            {
                m_Size = value;
                m_Bounds = default(Rect);
            }
        }

        private Size m_MinSize = default(Size);
        public Size MinSize
        {
            get
            {
                if (m_MinSize == default(Size))
                {
                    if (!this.Properties.ContainsKey("MinSize"))
                    {
                        return m_MinSize;
                    }
                    string size = this.Properties["MinSize"];
                    m_MinSize = new Size(ParseWidth(size), ParseHeight(size));
                }

                return m_MinSize;
            }
        }

        private Size m_MaxSize = default(Size);
        public Size MaxSize
        {
            get
            {
                if (m_MaxSize == default(Size))
                {
                    if (!this.Properties.ContainsKey("MaxSize"))
                    {
                        return m_MaxSize;
                    }
                    string size = this.Properties["MaxSize"];
                    m_MaxSize = new Size(ParseWidth(size), ParseHeight(size));
                }

                return m_MaxSize;
            }
        }

        private Rect m_Bounds = default(Rect);
        public Rect Bounds
        {
            get
            {
                if (m_Bounds == default(Rect))
                {
                    m_Bounds = new Rect(this.Location, this.Size);
                }

                return m_Bounds;
            }
        }

        private Point m_Location = default(Point);
        public Point Location
        {
            get
            {
                if (m_Location == default(Point))
                {
                    if (!this.Properties.ContainsKey("Location"))
                    {
                        return m_Location;
                    }
                    string location = this.Properties["Location"];
                    m_Location = new Point(ParseX(location), ParseY(location));
                }

                return m_Location;
            }
        }

        private string m_ControlName = default(string);
        public string ControlName
        {
            get
            {
                if (m_ControlName == default(string))
                {
                    if (!this.Properties.ContainsKey("ControlName"))
                    {
                        return m_ControlName;
                    }
                    m_ControlName = this.Properties["ControlName"];
                }

                return m_ControlName;
            }
        }

        private Rect m_Padding = default(Rect);
        public Rect Padding
        {
            get
            {
                if (m_Padding == default(Rect))
                {
                    if (!this.Properties.ContainsKey("Padding"))
                    {
                        return m_Padding;
                    }
                    string padding = this.Properties["Padding"];
                    m_Padding = ParseRect(padding);
                }

                return m_Padding;
            }
        }

        public bool IsTextVisible
        {
            get
            {
                if (!this.Properties.ContainsKey("TextVisible"))
                {
                    return false;
                }

                return this.Properties["TextVisible"].Equals(bool.TrueString, StringComparison.InvariantCultureIgnoreCase);
            }
        }

        public string Text
        {
            get
            {
                if (!this.Properties.ContainsKey("Text"))
                {
                    return string.Empty;
                }

                return this.Properties["Text"];
            }
        }

        private Size m_TextSize = default(Size);
        public Size TextSize
        {
            get
            {
                if (m_TextSize == default(Size))
                {
                    if (!this.Properties.ContainsKey("TextSize"))
                    {
                        return m_TextSize;
                    }
                    string size = this.Properties["TextSize"];
                    m_TextSize = new Size(ParseWidth(size), ParseHeight(size));
                }

                return m_TextSize;
            }
        }

        private AppearanceGroup m_AppearanceGroup = default(AppearanceGroup);
        public AppearanceGroup Appearance
        {
            get
            {
                if (m_AppearanceGroup == default(AppearanceGroup))
                {
                    if (this.Properties.ContainsKey("AppearanceGroup"))
                    {
                        //string appearance = this.Properties["AppearanceGroup"];
                        //using (XmlReader reader = 
                        m_AppearanceGroup = new AppearanceGroup("Tahoma, 8.25pt");
                    }
                }

                return m_AppearanceGroup;
            }
        }

        public TextLocation TextLocation
        {
            get
            {
                if (this.Properties.ContainsKey("TextLocation"))
                {
                    string textLocation = this.Properties["TextLocation"];
                    if (Enum.IsDefined(typeof(TextLocation), textLocation))
                    {
                        return (TextLocation)Enum.Parse(typeof(TextLocation), textLocation, true);
                    }
                }

                return TextLocation.Default;
            }
        }

        public int TextToControlDistance
        {
            get
            {
                if (this.Properties.ContainsKey("TextToControlDistance"))
                {
                    int distance;
                    if (int.TryParse(this.Properties["TextToControlDistance"], out distance))
                    {
                        return distance;
                    }
                }

                return default(int);
            }
        }

        private LayoutItemTypeName m_TypeName = LayoutItemTypeName.Unknown;
        public LayoutItemTypeName TypeName
        {
            get
            {
                if (m_TypeName == LayoutItemTypeName.Unknown &&
                    this.Properties.ContainsKey("TypeName"))
                {
                    string typeName = this.Properties["TypeName"];
                    if (Enum.IsDefined(typeof(LayoutItemTypeName), typeName))
                    {
                        m_TypeName = (LayoutItemTypeName)Enum.Parse(typeof(LayoutItemTypeName), typeName, true);
                    }
                }

                return m_TypeName;
            }
        }

        public string LayoutItemName
        {
            get
            {
                return this.GetProperty("Name");
            }
        }

        public string ParentName
        {
            get
            {
                return this.GetProperty("ParentName");
            }
        }

        private string GetProperty(string propertyName)
        {
            string name;
            this.Properties.TryGetValue(propertyName, out name);
            return name;
        }

        public bool IsRoot
        {
            get
            {
                return this.TypeName == LayoutItemTypeName.LayoutGroup &&
                    KnownLayoutItemName.Root.Equals(this.LayoutItemName);
            }
        }

        public string Name { get; private set; }
        public IDictionary<string, string> Properties { get; private set; }
    }

    public static class KnownLayoutItemName
    {
        public static readonly string Root = "Root";
        public static readonly string Customization = "Customization";
    }

    public class AppearanceGroup
    {
        public AppearanceGroup(string font)
        {
            this.Font = font;
            string[] parts = font.Split(',');
            if (parts.Length > 0)
            {
                this.FontFamily = parts[0].Trim();
            }
            if (parts.Length > 1)
            {
                this.FontSize = parts[1].Trim();
            }
        }

        public string Font { get; private set; }
        public string FontFamily { get; private set; }
        public string FontSize { get; private set; }
    }

    public enum TextLocation
    {
        Left,
        Top,
        Right,
        Bottom,
        Default = Left
    }

    public enum LayoutItemTypeName
    {
        LayoutControlItem,
        EmptySpaceItem,
        LayoutGroup,
        SimpleSeparator,
        SimpleLabelItem,
        Unknown
    }
}
